{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Security Posture Workflow\n",
    "\n",
    "A step by step example workflow to measure the security posture of a Kubernetes cluster using KubeHound."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Initial Setup\n",
    "\n",
    "Connection is being initated directly from the docker using the env vars `GRAPH_NOTEBOOK_HOST` and `GRAPH_NOTEBOOK_PORT`. To overwrite it you can use the magic `%%graph_notebook_config` [details here](https://github.com/aws/graph-notebook/tree/main/additional-databases/gremlin-server#connecting-to-a-local-gremlin-server-from-jupyter)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Workflow\n",
    "\n",
    "### High Level Metrics\n",
    "\n",
    "Let us get a high-level view of the security posture of the cluster. These metrics are not very nuanced but provide a top-level view of cluster security and easy tracking of improvements over time.\n",
    "\n",
    "First let's look at the shortest path from external service to a critical asset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%capture \"Remove this line to see debug information\"\n",
    "%%gremlin\n",
    "kh.services()\n",
    "    .has(\"runID\", graph.variables().get('runID_yourid').get())\n",
    "    .minHopsToCritical()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next let's see the total number of attacks paths originating from external services"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%gremlin\n",
    "kh.services()\n",
    "    .has(\"runID\", graph.variables().get('runID_yourid').get())\n",
    "    .criticalPaths().count()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exposed asset analyis\n",
    "\n",
    "The most likely entry points for an attacker into a Kubernetes cluster are:\n",
    "+ Exposed services via 0day, n-day, or misconfigurations\n",
    "+ Leaked credentials\n",
    "+ Supply chain attacks leading to execution within a container\n",
    "\n",
    "We can use KubeHound to evaluate the percentage of each of these entry points that can lead to a critical asset. First services:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%gremlin\n",
    "kh.V()\n",
    "    .has(\"runID\", graph.variables().get('runID_yourid').get())\n",
    "    .hasLabel(\"Endpoint\")\n",
    "    .has(\"exposure\", gte(2))    // https://kubehound.io/queries/dsl/#endpoint-exposure\n",
    "    .count()\n",
    "    .aggregate(\"t\")\n",
    "    .V()\n",
    "    .has(\"runID\", graph.variables().get('runID_yourid').get())\n",
    "    .hasLabel(\"Endpoint\")\n",
    "    .has(\"exposure\", gte(2))    // https://kubehound.io/queries/dsl/#endpoint-exposure\n",
    "    .hasCriticalPath()\n",
    "    .count()\n",
    "    .as(\"e\")\n",
    "    .math(\"100 * e/t\").by().by(unfold())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next credentials:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%gremlin\n",
    "kh.V()\n",
    "    .has(\"runID\", graph.variables().get('runID_yourid').get())\n",
    "    .hasLabel(\"Identity\")\n",
    "    .has(\"critical\", false)\n",
    "    .count()\n",
    "    .aggregate(\"t\")\n",
    "    .V()\n",
    "    .has(\"runID\", graph.variables().get('runID_yourid').get())\n",
    "    .hasLabel(\"Identity\")\n",
    "    .has(\"critical\", false)\n",
    "    .hasCriticalPath()\n",
    "    .count()\n",
    "    .as(\"e\")\n",
    "    .math(\"100 * e/t\").by().by(unfold())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Finally containers:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%gremlin\n",
    "kh.V()\n",
    "    .has(\"runID\", graph.variables().get('runID_yourid').get())\n",
    "    .hasLabel(\"Container\")\n",
    "    .count()\n",
    "    .aggregate(\"t\")\n",
    "    .V()\n",
    "    .has(\"runID\", graph.variables().get('runID_yourid').get())\n",
    "    .hasLabel(\"Container\")\n",
    "    .hasCriticalPath()\n",
    "    .count()\n",
    "    .as(\"e\")\n",
    "    .math(\"100 * e/t\").by().by(unfold())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Threat Modelling\n",
    "\n",
    "KubeHound can provide a high level overview of attack paths grouped by frequency in any given cluster via the DSL"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%gremlin\n",
    "kh.services()\n",
    "    .has(\"runID\", graph.variables().get('runID_yourid').get())\n",
    "    .criticalPathsFreq()"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
